package com.hc.java.transaction;

import lombok.Getter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 最原始的方法，Thread run()重写
 *
 * @author huangchao E-mail:fengquan8866@163.com
 * @version 创建时间：2024/6/20 20:34
 */
public class T00_F7 {
    private static class Boss extends Thread {
        private List<Worker> workers = new ArrayList<>();

        public void addTask(Worker t) {
            workers.add(t);
        }

        @Override
        public void run() {
            workers.forEach(Thread::start);
        }

        public void end(Worker worker) {
            if (worker.getResult() == Result.FAILED) {
                cancel(worker);
            }
        }

        public void cancel(Worker worker) {
            for (Worker w : workers) {
                if (w != worker) {
                    w.cancel();
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
        Boss boss = new Boss();
        Worker t1 = new Worker(boss, "t1", 3, true);
        Worker t2 = new Worker(boss, "t2", 4, true);
        Worker t3 = new Worker(boss, "t3", 1, false);

        boss.addTask(t1);
        boss.addTask(t2);
        boss.addTask(t3);

        // 启动线程
        boss.start();

        System.in.read();
    }

    private enum Result {
        NOTEND, SUCCESSED, FAILED, CANCELLED
    }

    private static class Worker extends Thread {
        @Getter
        private Result result = Result.NOTEND;
        @Getter
        private Boss boss;
        private String name;
        private int timeInSeconds;
        private boolean success;

        public Worker(Boss boss, String name, int timeInSeconds, boolean success) {
            this.boss = boss;
            this.name = name;
            this.timeInSeconds = timeInSeconds;
            this.success = success;
        }

        private volatile boolean cancelling = false;

        @Override
        public void run() {
            int interval = 100;
            int total = 0;
            for (; ; ) {
                try {
                    Thread.sleep(timeInSeconds);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                total += interval;
                if (total / 1000 >= timeInSeconds) {
                    System.out.println(name + " 任务结束！" + result);
                    this.result = success ? Result.SUCCESSED : Result.FAILED;
                    break;
                }
                if (cancelling) {
                    rollback();
                    result = Result.CANCELLED;
                    cancelling = false;
                    System.out.println(name + " 任务结束！" + result);
                    break;
                }
            }

            // 模拟业务执行时间
            // 实际中时间不固定，可能在处理计算任务，或者是IO任务
            boss.end(this);
        }

        private void rollback() {
            System.out.println(name + " rollback start...");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(name + " rollback end!");
        }

        public void cancel() {
            cancelling = true;
        }
    }
}
